/***************************************************************************
 *   Copyright (C) 2008 by Ivan Blagoev Topolsky   *
 *   ivan.topolsky@genebio.com   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include "dbsequencedigestorfactory.h"

namespace bol{


int DBSequenceDigestorFactory::fillCollection() {
  int r = 0;
  DBSequencePtr entry (new DBSequence ());

  do {
    // get next database entry
    if (! (m_factory->nextSequence(*entry))) {
       return r;
    }

    // cleave it !
    vector<int> pos;
    m_enzyme->cleavePositions(*(entry->sequence()), pos);
    pos.insert(pos.begin(), 1);
    pos.push_back(entry->sequence()->length()-1);

    // scan all found position 
    for (vector<int>::const_iterator i=pos.begin(); i<pos.end(); i++) {
      // at each position, take up to NumMisCleavage positions after that one to build candidate
      for (vector<int>::const_iterator j=i+1; (j<pos.end()) && (j <= i + m_nummiscleavage+1); j++) {
        // restrict lenght within range
        int l = *j - *i;
        if ((m_minlength > 0) && (l < m_minlength)) continue;
        if ((m_maxlength > 0) && (l > m_maxlength)) continue;

        // build the digested peptide from the database entry (while keeping a reference to the parent entry)
        PeptideFromSequencePtr ptr (new PeptideFromSequence(entry, *i, l));
        peptcollection.push_back(ptr);
        r++;
      }
    }
   // because sometimes lenght restrictions make us drop all possible peptides.
   // in case of :
   // - proteine sequence shorter than minlenght
   // - noncleavable proteine longer than maxlenght
  } while(! r); // repeat until we have at least a few peptides
  collectionsize += r;
  return r;
}


bool DBSequenceDigestorFactory::nextPeptide(PeptideFromSequencePtr &ptr) {
  if (collectionsize == 0) {
     if (fillCollection() == 0) 
        return false;
  }
  collectionsize--;
  ptr = *(peptcollection.begin());
  peptcollection.erase(peptcollection.begin());
  return true;
}

}
